package cn.melon.bz;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.apache.log4j.Logger;

import cn.melon.common.IConstant;
import cn.melon.common.Message;
import cn.melon.helper.IOnRequestListener;
import cn.melon.helper.LoggerHelper;
import cn.melon.helper.RequestMgr;

/**
 * 客户端后台socket线程, 在{@link cn.melon.bz.ClientThreadMgr}中管理
 * @author corvo
 */
public class ClientThread extends Thread {

    private final String TAG = LoggerHelper.makeLogTag(ClientThread.class);
    private final Logger threadLogger = LoggerHelper.clientLogger();

    private static final String SERVER_ADDRESS = IConstant.SERVER_ADDRESS;
    private static final int SERVER_PORT = IConstant.SERVER_PORT;

    private Socket socket = null;
    private boolean isOffline;

    /**
     * @param cardNum 传入学生学号, 将此线程保存到线程管理器中
     * @throws UnknownHostException 无法建立socket连接
     * @throws IOException 无法建立socket连接
     */
    public ClientThread(String cardNum) throws UnknownHostException, IOException {
        this.socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
        ClientThreadMgr.add(cardNum, this);
        isOffline = false;
    }

    @Override
    public void run() {
        while (!isOffline) {
            ObjectInputStream ois = null;
            Message msg = null;
            try {
                ois = new ObjectInputStream(socket.getInputStream());

                msg = (Message) ois.readObject();
                String recvID = msg.getReceicerID();

                // System.out.println(recvID);
                // System.out.println(msg.getData());

                // 通过receiverID获取处理函数
                IOnRequestListener listener = RequestMgr.getReceiver(recvID);
                if (listener != null) {
                    listener.onSuccess(msg.getData());
                }
            } catch (SocketException e) {
                this.isOffline = true;
                threadLogger.info(TAG + "服务器端已经下线");
            } catch (EOFException e) {
                this.isOffline = true;
                threadLogger.info(TAG + "服务器端已经下线");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 客户端主动下线, 当我们发现连接断开时, 会主动断线
     * @throws IOException socket断线
     */
    public void dispose() throws IOException {
        isOffline = true;
        this.socket.close();
    }

    public OutputStream getOutputStream() throws IOException {
        return socket.getOutputStream();
    }

    public InputStream getInputStream() throws IOException {
        return socket.getInputStream();
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public Socket getSocket() {
        return socket;
    }
}
